package acn.spring.shop.viewUtil;

import java.util.ArrayList;
import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;

public class PageWrapper<T> {

	private static final int MAX_PAGE_ITEM_DISPLAY = 5;

	private Page<T> page;
	private List<PageItem> items;
	private int currentNumber;
	private String url;
	private String sort;
	private int size;

	public PageWrapper(Page<T> page, String url) {
		initialize(page, url, null, MAX_PAGE_ITEM_DISPLAY);
	}

	public PageWrapper(Page<T> page, String url, int pageSize) {
		initialize(page, url, pageSize, MAX_PAGE_ITEM_DISPLAY);
	}

	public PageWrapper(Page<T> page, String url, int pageSize, int maxBarPage) {
		initialize(page, url, pageSize, maxBarPage);
	}

	private void initialize(Page<T> page, String url, Integer customPageSize, int maxBarPage) {
		this.page = page;
		this.url = url;
		items = new ArrayList<PageItem>();

		currentNumber = page.getNumber() + 1; // start from 1 to match page.page

		int start, size;
		if (page.getTotalPages() <= maxBarPage) {
			start = 1;
			size = page.getTotalPages();
		} else {
			size = maxBarPage;

			if (currentNumber <= maxBarPage - maxBarPage / 2) {
				start = 1;
			} else if (currentNumber >= page.getTotalPages() - maxBarPage / 2) {
				start = page.getTotalPages() - maxBarPage + 1;
			} else {
				start = currentNumber - maxBarPage / 2;
			}
		}

		for (int i = 0; i < size; i++) {
			items.add(new PageItem(start + i, (start + i) == currentNumber));
		}

		// size
		this.size = page.getSize();
		if (customPageSize != null) {
			this.size = customPageSize;
		}

		// sort
		Sort sort = page.getSort();
		if (sort != null) {
			Order order = sort.iterator().next();
			if (order != null) {
				this.sort = order.getProperty() + "," + order.getDirection().toString();
			}
		}
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public List<PageItem> getItems() {
		return items;
	}

	public int getNumber() {
		return currentNumber;
	}

	public List<T> getContent() {
		return page.getContent();
	}

	public int getSize() {
		return this.size;
	}

	public int getTotalPages() {
		return page.getTotalPages();
	}

	public boolean isFirstPage() {
		return page.isFirst();
	}

	public boolean isLastPage() {
		return page.isLast();
	}

	public boolean isHasPreviousPage() {
		return page.hasPrevious();
	}

	public boolean isHasNextPage() {
		return page.hasNext();
	}

	public String getSort() {
		return this.sort;
	}

	public class PageItem {
		private int number;
		private boolean current;

		public PageItem(int number, boolean current) {
			this.number = number;
			this.current = current;
		}

		public int getNumber() {
			return this.number;
		}

		public boolean isCurrent() {
			return this.current;
		}
	}
}
